package com.centurykounre.kettle.converters;


import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author yzj
 * @since 2024/8/16
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class Html2Map {
    private static final String KEY_EMPTY_VALUE = "empty_value";
    private static final String[] FIND_VAL_FROM_NEXT_KEY = new String[]{"出院医嘱"};
    private static final Set<String> FIND_VAL_FROM_NEXT_KEY_SET = Arrays.stream(FIND_VAL_FROM_NEXT_KEY).collect(java.util.stream.Collectors.toSet());

    public static Map<String, String> convert(String html) {
        val map = new HashMap<String, String>();
        val doc = Jsoup.parse(html);
        val ps = doc.getElementsByTag("table").get(0).getElementsByTag("p");
        for (val p : ps) {
            val spans = p.getElementsByTag("span");
            if (spans.isEmpty()) {
                continue;
            }
            val spanSize = spans.size();
            if (spanSize == 1) {
                val text = spans.get(0).text();
                val cTxt = text.replace(" ", "");
                if (cTxt.matches("\\d{4}年\\d{2}月\\d{2}日")) {
                    // 从上面正则提取年月日
                    String year = cTxt.substring(0, 4);
                    String month = cTxt.substring(5, 7);
                    String day = cTxt.substring(8, 10);
                    map.put("year", year);
                    map.put("month", month);
                    map.put("day", day);
                } else {
                    fillKeyVal(text, map);
                }
            } else {
                fillKeyVal2(spanSize, spans, map);
            }

        }
        return map;
    }

    private static void fillKeyVal(String text, Map<String, String> map) {
        int idx = text.indexOf("：");
        if (idx < 0) {
            idx = text.indexOf(":");
        }
        if (idx > 0) {
            map.remove(KEY_EMPTY_VALUE);
            String key = text.substring(0, idx);
            String value = text.substring(idx + 1);
            if (FIND_VAL_FROM_NEXT_KEY_SET.contains(key) && value.trim().isEmpty()) {
                map.put(KEY_EMPTY_VALUE, key);
            }
            map.put(key, value);
        } else if (map.containsKey(KEY_EMPTY_VALUE)) {
            val key = map.get(KEY_EMPTY_VALUE);
            map.put(key, map.get(key) + "\n" + text);
        }
    }

    private static void fillKeyVal2(int spanLen, Elements spans, Map<String, String> map) {
        int i = 0;
        while (i < spanLen - 1) {
            val text = spans.get(i).text();
            if (text.endsWith(":") || text.endsWith("：")) {
                i = convert01(spans, map, text, i);
            } else if (text.contains(":") || text.contains("：")) {
                i = convert02(spanLen, spans, map, text, i);
            } else {
                i += 2;
            }
        }
    }

    private static int convert01(Elements spans, Map<String, String> map, String text, int i) {
        val key = text.replace("：", "").replace(":", "");
        if (key.trim().isEmpty()) {
            i += 1;
        } else {
            val value = spans.get(i + 1).text();
            map.put(key, value);
            i += 2;
        }
        return i;
    }

    private static int convert02(int spanLen, Elements spans, Map<String, String> map, String text, int i) {
        int idx = text.indexOf("：");
        if (idx < 0) {
            idx = text.indexOf(":");
        }
        val key = text.substring(0, idx);
        val value = new StringBuilder(text.substring(idx + 1));
        for (int j = i + 1; j < spanLen; j++) {
            value.append("\t").append(spans.get(j).text());
        }
        map.put(key, value.toString());
        return spanLen;
    }

    public static void main(String[] args) {
        log.info("Starting Html2Map");
    }
}
